"""
认证路由（注册 / 登录 / 获取当前用户信息）
统一使用 ApiResponse 及 BizException
"""
from datetime import timedelta
from typing import Annotated

from fastapi import APIRouter, Depends, Response
from fastapi.security import OAuth2PasswordRequestForm

from app.common.auth import get_current_user
from app.common.common import DbDep
from app.common.security import verify_password, create_access_token
from app.crud.user_crud import (
	create_user,
	username_exists,
	email_exists,
	get_user_by_id,
	get_user_by_username,
	get_user_roles,
)
from app.schemas.auth_schemas import TokenOut
from app.schemas.system_schemas import RoleResponse
from app.schemas.user_schemas import UserCreate, UserResponse, UserInDB, UserProfileResponse
from common.config import settings
from common.exceptions import BizException, ErrorCode
from common.response import ApiResponse

router = APIRouter(prefix="/auth", tags=["Authentication"])


# ---------- 登录 ----------
@router.post("/token", response_model=ApiResponse[TokenOut])
async def oauth2_token(
		form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
		db: DbDep,
) -> ApiResponse[TokenOut]:
	"""OAuth2 规范登录获取 JWT 令牌"""
	if not form_data.username or not form_data.password:
		raise BizException.from_error_code(ErrorCode.BAD_REQUEST, message="用户名/密码不能为空")

	user = await get_user_by_username(db, form_data.username)
	if not user or not verify_password(form_data.password, user.hashed_password):
		raise BizException.from_error_code(
			ErrorCode.INVALID_CREDENTIALS,
			headers={"WWW-Authenticate": "Bearer"}
		)
	if user.disabled:
		raise BizException.from_error_code(ErrorCode.USER_DISABLED, headers={"WWW-Authenticate": "Bearer"})

	access_token_expires = timedelta(minutes=settings.access_token_expire_minutes)
	token = create_access_token(data={"sub": user.username}, expires_delta=access_token_expires)
	return ApiResponse.success(TokenOut(access_token=token, token_type="Bearer"))


@router.post("/login", response_model=ApiResponse[TokenOut])
async def login(
		form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
		db: DbDep,
) -> ApiResponse[TokenOut]:
	"""业务友好登录入口（与 /token 等效）"""
	return await oauth2_token(form_data, db)


# ---------- 注册 ----------
@router.post("/register", response_model=ApiResponse[UserResponse])
async def register(
		user: UserCreate,
		db: DbDep,
) -> ApiResponse[UserResponse]:
	"""新用户注册"""
	if await username_exists(db, user.username):
		raise BizException.from_error_code(ErrorCode.USERNAME_EXISTS)
	if await email_exists(db, user.email):
		raise BizException.from_error_code(ErrorCode.EMAIL_EXISTS)

	user_id = await create_user(db, user)
	new_user = await get_user_by_id(db, user_id)
	return ApiResponse.success(UserResponse.model_validate(new_user))


# ---------- 登出 ----------
@router.post("/logout")
async def logout(
		response: Response,
		current_user: UserInDB = Depends(get_current_user),
) -> ApiResponse[dict]:
	"""登出：清除 Cookie（如用）TODO 后续需要增加Redis名单，处理实际登出效果"""
	response.delete_cookie("Authorization")
	return ApiResponse.success(message="登出成功")


# ---------- 当前用户 ----------
@router.get("/profile", response_model=ApiResponse[UserProfileResponse])
async def get_current_user_profile(
		db: DbDep,
		current_user: UserInDB = Depends(get_current_user),
) -> ApiResponse[UserProfileResponse]:
	"""获取当前用户信息（包含角色信息）"""
	try:
		# 获取用户角色信息
		user_roles = await get_user_roles(db, current_user.user_code)
		roles = [RoleResponse.model_validate(role) for role in user_roles]

		# 构建用户信息响应
		user_profile = UserProfileResponse.model_validate(current_user)
		user_profile.roles = roles

		return ApiResponse.success(user_profile)
	except Exception as e:
		raise BizException.from_error_code(ErrorCode.INTERNAL_SERVER_ERROR, message=f"获取用户信息失败: {str(e)}")
